// Copyright (c)  YISH. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace NSQL.Extensions
{
    [SuppressMessage("ReSharper", "IdentifierTypo")]
    [SuppressMessage("ReSharper", "UnusedMember.Global")]
    public static class JoinableExtensions
    {
        public static IJoinable Origin(this IJoinable self)
        {
            while (self is JoinNode joinNode)
            {
                self = joinNode.Base;
            }

            return self;
        }

        public static IEnumerable<IJoinable> Items(this IJoinable self)
        {
            if (self is null) yield break;
            yield return self;
            while (self is JoinNode joinNode)
            {
                self = joinNode.Base;
                yield return self;
            }
        }
        
        public static JoinBuilder Join(this IJoinable self, IJoinable joinTable, JoinType type)
        {
            return JoinBuilder.Join(self, joinTable, type);
        }

        public static JoinBuilder FullJoin(this IJoinable self, IJoinable joinTable)
        {
            return JoinBuilder.FullJoin(self, joinTable);
        }

        public static JoinBuilder FullJoin(this IJoinable self, Table joinTable)
        {
            return JoinBuilder.FullJoin(self, joinTable);
        }

        public static JoinBuilder LeftJoin(this IJoinable self, IJoinable joinTable)
        {
            return JoinBuilder.LeftJoin(self, joinTable);
        }

        public static JoinBuilder LeftJoin(this IJoinable self, Table joinTable)
        {
            return JoinBuilder.LeftJoin(self, joinTable);
        }

        public static JoinBuilder RightJoin(this IJoinable self, IJoinable joinTable)
        {
            return JoinBuilder.RightJoin(self, joinTable);
        }

        public static JoinBuilder RightJoin(this IJoinable self, Table joinTable)
        {
            return JoinBuilder.RightJoin(self, joinTable);
        }


        public static JoinBuilder LeftOuterJoin(this IJoinable self, IJoinable joinTable)
        {
            return JoinBuilder.LeftOuterJoin(self, joinTable);
        }

        public static JoinBuilder LeftOuterJoin(this IJoinable self, Table joinTable)
        {
            return JoinBuilder.LeftOuterJoin(self, joinTable);
        }

        public static JoinBuilder RightOuterJoin(this IJoinable self, IJoinable joinTable)
        {
            return JoinBuilder.RightOuterJoin(self, joinTable);
        }

        public static JoinBuilder RightOuterJoin(this IJoinable self, Table joinTable)
        {
            return JoinBuilder.RightOuterJoin(self, joinTable);
        }

        public static JoinBuilder InnerJoin(this IJoinable self, IJoinable joinTable)
        {
            return JoinBuilder.InnerJoin(self, joinTable);
        }

        public static JoinBuilder InnerJoin(this IJoinable self, Table joinTable)
        {
            return JoinBuilder.InnerJoin(self, joinTable);
        }

        public static JoinBuilder CrossJoin(this IJoinable self, IJoinable joinTable)
        {
            return JoinBuilder.CrossJoin(self, joinTable);
        }

        public static JoinBuilder CrossJoin(this IJoinable self, Table joinTable)
        {
            return JoinBuilder.CrossJoin(self, joinTable);
        }
    }
}